package seismosurfer.gui;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;

import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JComponent;

import seismosurfer.util.SeismoException;
import seismosurfer.util.TimeUtil;

import com.bbn.openmap.util.Debug;

/**
 * A date selector consisting of 3 combo boxes.
 * 
 */
public class DateSelector extends JComponent {
    
    private static final long serialVersionUID = 2088051229245970981L;

    private Calendar cal = Calendar.getInstance();

    private JComboBox yearList, monthList, dayList;

    private String yearSel, monthSel, daySel;

    /**
     * Constructs a date selector for the time between <em>dnLimit</em> and
     * <em>upLimit</em> and initializes to <em>initVal</em>.
     * 
     * @param initVal the initial value 
     * @param dnLimit the lowest possible value
     * @param upLimit the toppest possible value
     */
    public DateSelector(long initVal, long dnLimit, long upLimit) {

        create(initVal, dnLimit, upLimit);

    }
    
    
    protected String[] getYears(long dnLimit, long upLimit) {
        if (upLimit < dnLimit)
            throw new SeismoException(
                    "Top time limit cannot be lower than bottom time limit.");

        String result[];

        int yearMin = TimeUtil.getYear(dnLimit);
        int yearMax = TimeUtil.getYear(upLimit);

        result = new String[yearMax - yearMin + 1];

        for (int i = 0; i < result.length; i++) {
            result[i] = String.valueOf(yearMin + i);
        }

        return result;
    }
    
    /**
     * Creates the widgets which this component is
     * consisted of and sets listeners to them.
     * 
     * @param initVal the initial value 
     * @param dnLimit the lowest possible value
     * @param upLimit the toppest possible value
     */
    protected void create(long initVal, long dnLimit, long upLimit) {

        try {

            int i;

            int monthStrSize = 12;
            String[] monthStr = new String[monthStrSize];

            int dayStrSize = 31;
            String[] dayStr = new String[dayStrSize];

            for (i = 0; i < monthStrSize; i++) {
                monthStr[i] = "" + (1 + i);
            }
            for (i = 0; i < dayStrSize; i++) {
                dayStr[i] = "" + (1 + i);
            }

            yearList = new JComboBox(getYears(dnLimit, upLimit));
            monthList = new JComboBox(monthStr);
            dayList = new JComboBox(dayStr);

            yearList.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JComboBox cb = (JComboBox) e.getSource();
                    yearSel = (String) cb.getSelectedItem();
                }
            });
            monthList.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JComboBox cb = (JComboBox) e.getSource();
                    monthSel = (String) cb.getSelectedItem();
                }
            });
            dayList.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JComboBox cb = (JComboBox) e.getSource();
                    daySel = (String) cb.getSelectedItem();
                }
            });

            setSelectedDate(initVal);

            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
            add(yearList);
            add(monthList);
            add(dayList);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    
    /**
     * Sets the given date on the this components`
     * widgets.
     * 
     * @param date
     */
    public void setSelectedDate(long date) {

        Calendar selCal = Calendar.getInstance();
        selCal.setTimeInMillis(date);

        yearSel = String.valueOf(TimeUtil.getYear(date));

        monthSel = String.valueOf(selCal.get(Calendar.MONTH) + 1);
        daySel = String.valueOf(selCal.get(Calendar.DAY_OF_MONTH));

        yearList.setSelectedItem(yearSel);
        monthList.setSelectedItem(monthSel);
        dayList.setSelectedItem(daySel);
    }

    /**
     * Gets the date.
     * 
     * @return The date in milliseconds.
     */
    public long getValue() {

        cal.clear();

        TimeUtil.setYear(cal, Integer.parseInt(yearSel));

        cal.set(Calendar.MONTH, Integer.parseInt(monthSel) - 1);
        cal.set(Calendar.DATE, Integer.parseInt(daySel));

        Debug.output("Date:" + TimeUtil.toText(cal.getTimeInMillis()));

        return cal.getTimeInMillis();
    }

    public Dimension getPreferredSize() {
        Dimension d1 = yearList.getPreferredSize();
        Dimension d2 = monthList.getPreferredSize();
        Dimension d3 = dayList.getPreferredSize();
        return new Dimension(d1.width + d2.width + d3.width, d1.height);
    }

}
